package cn.chiship.framework.business.core.aspect;

import cn.chiship.framework.common.annotation.JobAnnotation;
import cn.chiship.framework.common.pojo.dto.QuartzJobLogDto;
import cn.chiship.sdk.core.util.StringUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 日志记录AOP实现
 *
 * @author lijian
 */
@Aspect
@Component
public class JobLogAspect {

	private static final Logger LOGGER = LoggerFactory.getLogger(JobLogAspect.class);

	/**
	 * 开始时间
	 */
	private long startTime = 0L;

	/**
	 * 结束时间
	 */
	private long endTime = 0L;

	@Before("execution(* *..core.task..*.*(..))")
	public void doBeforeInServiceLayer(JoinPoint joinPoint) {
		LOGGER.debug("doBeforeInServiceLayer");
		startTime = System.currentTimeMillis();
	}

	@After("execution(* *..core.task..*.*(..))")
	public void doAfterInServiceLayer(JoinPoint joinPoint) {
		LOGGER.debug("doAfterInServiceLayer");
	}

	@Around("execution(* *..core.task..*.*(..))")
	public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
		/**
		 * 从注解中获取操作名称、获取响应结果
		 */
		Object result = pjp.proceed();
		Signature signature = pjp.getSignature();
		MethodSignature methodSignature = (MethodSignature) signature;
		Method method = methodSignature.getMethod();
		Object[] args = pjp.getArgs();
		JobAnnotation jobAnnotation = method.getAnnotation(JobAnnotation.class);
		if (StringUtil.isNull(jobAnnotation)) {
			return result;
		}

		endTime = System.currentTimeMillis();
		String methodName = method.getName();
		String className = method.getDeclaringClass().getSimpleName();
		String fullClassName = method.getDeclaringClass().getCanonicalName();
		Class[] exceptionTypes = method.getExceptionTypes();
		int spendTime = (int) (endTime - startTime);

		QuartzJobLogDto quartzJobLogDto = new QuartzJobLogDto();
		quartzJobLogDto.setJobName(jobAnnotation.value());
		quartzJobLogDto.setJobClass(className);
		quartzJobLogDto.setJobMethod(methodName);
		quartzJobLogDto.setInvokeTarget(fullClassName);
		if (args.length > 0) {
			quartzJobLogDto.setJobParam(args[0].toString());
		}
		quartzJobLogDto.setJobMessage(jobAnnotation.value() + " 总共耗时" + spendTime + "毫秒");
		quartzJobLogDto.setStartTime(startTime);
		quartzJobLogDto.setSpendTime(spendTime);
		if (exceptionTypes.length == 0) {
			quartzJobLogDto.setStatus(Byte.valueOf("0"));
			quartzJobLogDto.setExceptionInfo("-");
		}
		else {
			quartzJobLogDto.setStatus(Byte.valueOf("1"));
		}
		return result;
	}

}
